package net.surina.soundtouch

/**
 * Created by [Jason Xue](mailto:jasonxue@tinnove.com.cn) on 2025/4/23.
 */
class SoundTouch(sampleRate: Int, channelCount: Int) {
    private external fun setTempo(handle: Long, tempo: Float)
    private external fun setTempoChange(handle: Long, tempoChange: Float)
    private external fun setChannelCount(handle: Long, channelCount: Int)
    private external fun setSampleRate(handle: Long, sampleRate: Int)
    private external fun setPitchSemiTones(handle: Long, pitch: Float)
    private external fun setSpeed(handle: Long, speed: Float)
    private external fun setSpeedChange(handle: Long, speedChange: Float)

    private external fun processFile(handle: Long, inputFile: String, outputFile: String): Int
    private external fun deleteInstance(handle: Long)

    private external fun putSamples(handle: Long, samples: ShortArray, len: Int)
    private external fun receiveSamples(handle: Long, outputBuf: ShortArray): Int

    private var handle: Long = 0

    init {
        handle = newInstance()
        setSampleRate(handle, sampleRate)
        setChannelCount(handle, channelCount)
    }

    fun close() {
        deleteInstance(handle)
        handle = 0
    }

    fun setTempo(tempo: Float) {
        setTempo(handle, tempo)
    }

    fun setSpeedChange(speedChange: Float) {
        setSpeedChange(handle, speedChange)
    }


    fun setPitchSemiTones(pitch: Float) {
        setPitchSemiTones(handle, pitch)
    }

    fun setSpeed(speed: Float) {
        setSpeed(handle, speed)
    }

    fun setTempoChange(tempoChange: Float) {
        setTempoChange(handle, tempoChange)
    }

    fun processFile(inputFile: String, outputFile: String): Int {
        return processFile(handle, inputFile, outputFile)
    }

    fun putSamples(samples: ShortArray, len: Int) {
        putSamples(handle, samples, len)
    }

    fun receiveSamples(outputBuf: ShortArray): Int {
        return receiveSamples(handle, outputBuf)
    }

    companion object {
        // Native interface function that returns SoundTouch version string.
        // This invokes the native c++ routine defined in "soundtouch-jni.cpp".
        @JvmStatic
        external fun getVersionString(): String

        @JvmStatic
        external fun getErrorString(): String

        @JvmStatic
        private external fun newInstance(): Long

        // Load the native library upon startup
        init {
            System.loadLibrary("soundtouch")
        }
    }
}